package cz.jakol.scanner.tools;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import javax.swing.JOptionPane;

// TODO udelat metodu log(String type, String message)
// tu potom volat z logInfo, logError a logWarning

/**
 *
 * @author Jakub Koláček <admin@jakol.cz>
 * @version 0.0.4-SNAPSHOT
 */
public class Logger extends Thread {
    private String logsFolder = "logs/";
    private String logName;
    private boolean logPathOk = false;
    
    /**
     * 
     * @param logName Filename of log. If not exists, it'll be created 
     */
    public Logger(String logName){
	this.logName = logName;
    }
    
    /**
     * 
     * @param logName Filename of log. If not exists, it'll be created
     * @param logsFolder Name of folder with logs
     */
    public Logger(String logName, String logsFolder){
	this.logName = logName;
	this.logsFolder = logsFolder;
        this.fixLogPath();
    }
    
    @Override
    public void run(){
        
    }
    
    /**
     * Logs messages with [INFO] tag. Should be used for debug messages.
     * 
     * @param message Info message that should be logged
     */
    public void logInfo(String message){
	StringBuilder sb = this.createBasicString("info");
        BufferedWriter output = this.openFile();
        sb.append(message);
        try {
            output.append(sb);
            output.newLine();
            output.flush();
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Error writing to file: "+ex.getMessage());
        } finally {
            if(output != null){
                try {
                    output.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    /**
     * Logs messages with [ERROR] tag. Should be used for error messages.
     * @param message 
     */
    public void logError(String message){
	StringBuilder sb = this.createBasicString("error");
        BufferedWriter output = this.openFile();
        sb.append(message);
        try {
            output.append(sb);
            output.newLine();
            output.flush();
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Error writing to file: "+ex.getMessage());
        } finally {
            if(output != null){
                try {
                    output.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    /**
     * Logs messages with [WARNING] tag. Should be used for warnings.
     * @param message 
     */
    public void logWarning(String message){
	StringBuilder sb = this.createBasicString("warning");
        BufferedWriter output = this.openFile();
        sb.append(message);
        try {
            output.append(sb);
            output.newLine();
            output.flush();
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Error writing to file: "+ex.getMessage());
        } finally {
            if(output != null){
                try {
                    output.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    /**
     * 
     * @param logName Filename of log. If not exists, it'll be created
     */
    public void setLogName(String logName){
	this.logName = logName;
    }
    
    /**
     * 
     * @return String name of actual log file
     */
    public String getLogName(){
	return this.logName;
    }
    
    private StringBuilder createBasicString(String type){
        StringBuilder sb = new StringBuilder();
        sb.append(new SimpleDateFormat("yyyy-MM-dd\tHH:mm:ss.S\t").format(new Date())+"["+type.toUpperCase()+"] ");
        
        return sb;
    }
    
    private void fixLogPath(){
	if(!this.logsFolder.endsWith("/")){
	    this.logsFolder+="/";
	}
        this.logPathOk = true;
    }
    
    private BufferedWriter openFile(){
        BufferedWriter bw = null;
        try {
            // TODO udělat zepár kontrol
            // pokud tohle zdechne, tak to zapsat do souboru loggerError.log
            File f = new File(this.logsFolder+this.logName);
            if(f.exists()&&f.canWrite()){
                bw = new BufferedWriter(new FileWriter(f, true));
            }else if(f.getParentFile().mkdirs() && f.createNewFile()){
                bw = new BufferedWriter(new FileWriter(f));
            }else{
                JOptionPane.showMessageDialog(null, "Nepodařilo se vytvořit logovací soubor.");
            }
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Logger exception: "+ex.getMessage(), "Error saving log", JOptionPane.ERROR_MESSAGE);
        }
	return bw;
    }
}
